"""
文件处理工具
提供文件上传、处理和存储功能
"""
import os
import uuid
import time
from werkzeug.utils import secure_filename
from PIL import Image
from flask import current_app


ALLOWED_EXTENSIONS = {
    'image': {'png', 'jpg', 'jpeg', 'gif', 'webp'},
    'document': {'pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt'},
    'archive': {'zip', 'rar', '7z', 'tar', 'gz'}
}


def allowed_file(filename, file_type=None):
    """
    检查文件扩展名是否允许
    
    参数:
        filename: 文件名
        file_type: 文件类型 (image, document, archive 或 None 表示任何允许的类型)
    
    返回:
        文件是否允许
    """
    if '.' not in filename:
        return False
    
    ext = filename.rsplit('.', 1)[1].lower()
    
    if file_type:
        return ext in ALLOWED_EXTENSIONS.get(file_type, set())
    else:
        # 检查所有允许的扩展名
        all_allowed = set()
        for extensions in ALLOWED_EXTENSIONS.values():
            all_allowed.update(extensions)
        return ext in all_allowed


def save_file(file, folder=None, file_type=None, resize=None):
    """
    保存上传的文件
    
    参数:
        file: 上传的文件对象
        folder: 保存的子文件夹
        file_type: 文件类型限制
        resize: 如果是图片，调整大小 (宽, 高)
    
    返回:
        保存的文件路径和URL
    """
    if not file or file.filename == '':
        return None, None
    
    # 确保文件名安全
    filename = secure_filename(file.filename)
    
    # 检查文件类型
    if not allowed_file(filename, file_type):
        current_app.logger.warning(f"不允许的文件类型: {filename}")
        return None, None
    
    # 生成唯一文件名
    ext = filename.rsplit('.', 1)[1].lower()
    unique_filename = f"{int(time.time())}_{uuid.uuid4().hex}.{ext}"
    
    # 确定保存路径
    upload_folder = current_app.config['UPLOAD_FOLDER']
    if folder:
        target_folder = os.path.join(upload_folder, folder)
        os.makedirs(target_folder, exist_ok=True)
    else:
        target_folder = upload_folder
    
    file_path = os.path.join(target_folder, unique_filename)
    
    # 如果是图片且需要调整大小
    if resize and file_type == 'image':
        try:
            # 保存原始文件到临时位置
            temp_path = os.path.join(target_folder, f"temp_{unique_filename}")
            file.save(temp_path)
            
            # 调整大小
            with Image.open(temp_path) as img:
                img = img.resize(resize, Image.LANCZOS)
                img.save(file_path)
            
            # 删除临时文件
            os.remove(temp_path)
        except Exception as e:
            current_app.logger.error(f"处理图片时出错: {str(e)}")
            return None, None
    else:
        # 直接保存文件
        file.save(file_path)
    
    # 计算相对路径用于URL
    rel_path = os.path.relpath(file_path, upload_folder)
    url = f"/uploads/{rel_path.replace(os.sep, '/')}"
    
    return rel_path, url


def delete_file(file_path):
    """
    删除文件
    
    参数:
        file_path: 文件的相对路径
    
    返回:
        是否成功删除
    """
    if not file_path:
        return False
    
    full_path = os.path.join(current_app.config['UPLOAD_FOLDER'], file_path)
    
    try:
        if os.path.exists(full_path):
            os.remove(full_path)
            return True
    except Exception as e:
        current_app.logger.error(f"删除文件时出错: {str(e)}")
    
    return False 